# coding:utf-8
# writingtime: 2022-8-4
# reference: https://doi.org/10.1007/s40815-021-01243-2

from DistanceFunction.euclidean import Euclidean


class T:
    def __init__(self, dataList, membershipMatrix, clusterCenter, m=2):
        """
        function
        :param dataList: 样本向量
        :param membershipMatrix: 关系矩阵
        :param clusterCenter: 聚合中心
        :param m: 聚合参数
        """
        self.dataList = dataList
        self.membershipMatrix = membershipMatrix
        self.clusterCenter = clusterCenter
        self.m = m

    def getsum1(self):
        """
        function: 计算第一部分的累加和
        :return:
        """
        sum1 = 0
        for i in range(len(self.clusterCenter)):
            for j in range(len(self.dataList)):
                sum1 += (self.membershipMatrix[i][j] ** self.m) * (
                        Euclidean.getresult(self.dataList[j], self.clusterCenter[i]) ** 2)
        return sum1

    def getsum2(self):
        """
        function: 计算第二个累加和
        :return:
        """
        sum1 = 0
        for i in range(len(self.clusterCenter)):
            for k in range(len(self.clusterCenter)):
                if i != k:
                    sum1 += Euclidean.getresult(self.clusterCenter[i], self.clusterCenter[k]) ** 2
        sum1 /= (len(self.clusterCenter) * (len(self.clusterCenter) + 1))
        return sum1

    def gettang(self):
        """
        function: 计算Tango评价
        :return:
        """
        li_temp = []
        for i in range(len(self.clusterCenter)):
            for k in range(len(self.clusterCenter)):
                if i != k:
                    li_temp.append(Euclidean.getresult(self.clusterCenter[i], self.clusterCenter[k]) ** 2)
        minvalue = min(li_temp)
        value = (self.getsum1() + self.getsum2()) / (minvalue + 1 / len(self.clusterCenter))
        return value

    @staticmethod
    def getresult(dataList, membershipMatrix, clusterCenter, m=2, a=2):
        """
        function: t评价函数
        :param dataList: 样本向量
        :param membershipMatrix: 评价矩阵
        :param clusterCenter: 中心点向量
        :param m: 聚合参数
        :return: XieBeni评价值
        """
        return T(dataList, membershipMatrix, clusterCenter, m).gettang()
